package com.dabai.opdoubleopen;

import android.annotation.SuppressLint;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.afollestad.materialdialogs.MaterialDialog;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.dabai.opdoubleopen.adapter.AppAdapter;
import com.dabai.opdoubleopen.bean.AppBaseInfo;
import com.dabai.opdoubleopen.databinding.ActivityMainBinding;
import com.dabai.opdoubleopen.shizuku.Shell;
import com.dabai.opdoubleopen.shizuku.ShizukuShell;
import com.dabai.opdoubleopen.ui.SettingsActivity;
import com.dabai.opdoubleopen.utils.AppUtils;
import com.dabai.opdoubleopen.utils.DabaiUtils;
import com.dabai.opdoubleopen.utils.ShellUtils;
import com.dabai.opdoubleopen.view.DividerGridItemDecoration;
import com.dabai.utils.FileUtils;
import com.github.promeg.pinyinhelper.Pinyin;
import com.permissionx.guolindev.PermissionX;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.crashreport.CrashReport;

import java.io.IOException;
import java.util.ArrayList;

import me.zhanghai.android.appiconloader.AppIconLoader;
import me.zhanghai.android.fastscroll.FastScrollerBuilder;
import moe.shizuku.api.ShizukuApiConstants;


public class MainActivity extends AppCompatActivity {

    ActivityMainBinding amb;
    private AppAdapter adapter;
    Context context;
    private MaterialDialog progressDialog;

    public static String TAG = "LogTag";
    private ArrayList<String> packageNames;

    private ArrayList<AppBaseInfo> appBaseInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        amb = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(amb.getRoot());
        context = getApplicationContext();

        new FastScrollerBuilder(amb.recyclerView).build();

        amb.recyclerView.setLayoutManager(new LinearLayoutManager(this));
        amb.recyclerView.addItemDecoration(new DividerGridItemDecoration(this));

        progressDialog = new MaterialDialog.Builder(this)
                .title(R.string.tip)
                .progress(true, 0)
                .build();

        progressDialog.setContent(R.string.application_is_loading_list);
        progressDialog.show();

        AppIconLoader appIconLoader = new AppIconLoader(100, true, context);

        new Thread(() -> {

            packageNames = AppUtils.getAllAppPackages(context);
            appBaseInfo = new ArrayList<>();

            ArrayList<String> Tool_appNames = new ArrayList<>();
            ArrayList<String> Tool_package = new ArrayList<>();
            ArrayList<String> Tool_apkPath = new ArrayList<>();


            for (String packageName : packageNames) {

                AppBaseInfo appInfo = new AppBaseInfo();

                appInfo.setPackageName(packageName);
                appInfo.setAppName(AppUtils.getApplicationNameByPackageName(context, packageName));
                //这两行是准备工具箱的文件
                Tool_appNames.add(AppUtils.getApplicationNameByPackageName(context, packageName));
                Tool_package.add(packageName);
                Tool_apkPath.add(AppUtils.getAppSourceByPackageName(context, packageName));


                try {
                    ApplicationInfo applicationInfo = AppUtils.getApplicationInfoByPackageName(context, packageName);
                    appInfo.setIcon(appIconLoader.loadIcon(applicationInfo));

                } catch (Exception e) {
                    //尝试修复 图标加载 导致的空指针
                    appInfo.setIcon(drawable2Bitmap(AppUtils.getApplicationIconByPackageName(context,packageName)));
                }


                appBaseInfo.add(appInfo);
            }

            try {
                String appNames = Tool_appNames.toString();
                String packages = Tool_package.toString();
                String apkPath = Tool_apkPath.toString();

                FileUtils.writeText(getExternalFilesDir("toolbox").getPath()+"/AppNames.txt",appNames.substring(1,appNames.length()-1).trim().replace(" ",""),true);
                FileUtils.writeText(getExternalFilesDir("toolbox").getPath()+"/Package.txt",packages.substring(1,packages.length()-1).trim().replace(" ",""),true);
                FileUtils.writeText(getExternalFilesDir("toolbox").getPath()+"/apkPath.txt",apkPath.substring(1,apkPath.length()-1).trim().replace(" ",""),true);
                Log.d(TAG, "onCreate: 工具箱所需文件写出成功!");
            } catch (IOException e) {
                Log.d(TAG, "onCreate: "+e);
            }

            try {
                appBaseInfo.sort((o1, o2) -> {

                    char o1pinyin = Pinyin.toPinyin(o1.getAppName().charAt(0)).charAt(0);
                    char o2pinyin = Pinyin.toPinyin(o2.getAppName().charAt(0)).charAt(0);

                    return String.valueOf(o1pinyin).compareTo(String.valueOf(o2pinyin));
                });
            } catch (Exception e) {
                e.printStackTrace();
            }

            adapter = new AppAdapter(appBaseInfo);
            adapter.setAnimationEnable(true);
            adapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.ScaleIn);

            runOnUiThread(() -> {
                amb.recyclerView.setAdapter(adapter);
                progressDialog.dismiss();

                if (DabaiUtils.isActivityFirstOpen(this)) {
                    if (!Build.MODEL.toUpperCase().contains("OnePlus".toUpperCase())) {
                        new MaterialDialog.Builder(this)
                                .title(R.string.tip)
                                .content("本软件不保证非OnePlus手机能够双开成功，并且不推荐其他机型和非一加系统使用。")
                                .positiveText("确认")
                                .show();
                    }else {
                        DabaiUtils.showDialog(this, "请先使用系统自带双开功能，双开任意应用一次，之后再用本应用。");
                    }
                }

                // 设置点击事件
                adapter.setOnItemClickListener((adapter, view, position) -> {

                    String name = appBaseInfo.get(position).getAppName();
                    String packageName = appBaseInfo.get(position).getPackageName();
                    String path = AppUtils.getAppSourceByPackageName(context, packageName);

                    checkPermissions(name, path);

                });

            });
        }).start();


    }


    Bitmap drawable2Bitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof NinePatchDrawable) {
            Bitmap bitmap = Bitmap
                    .createBitmap(
                            drawable.getIntrinsicWidth(),
                            drawable.getIntrinsicHeight(),
                            drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                                    : Bitmap.Config.RGB_565);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        } else {
            return null;
        }
    }


    /**
     * 检查权限
     */
    private void checkPermissions(String name, String basePath) {
        //检查授权方式
        SharedPreferences sp = context.getSharedPreferences(getPackageName() + "_preferences", 0);
        String mode = sp.getString("mode", "null");

        switch (mode) {
            case "null":
            case "root":
                if (!DabaiUtils.isRoot()) {
                    DabaiUtils.showDialog(this, context.getString(R.string.didnot_get_to_root));
                } else {

                    new MaterialDialog.Builder(this)
                            .title(R.string.tip)
                            .content("[root] 确定要双开 \"" + name + "\" 嘛？")
                            .positiveText(R.string.yes)
                            .onPositive((dialog, which) -> {

                                progressDialog.setContent("正在尝试双开 \"" + name + "\" ,请稍等...");
                                progressDialog.show();

                                new Thread(() -> {
                                    //尝试双开
                                    ShellUtils.CommandResult commandResult = ShellUtils.execCommand("pm install -r --user " + DabaiUtils.getSharedPreferencesString(context, "user", "999") + " " + basePath, true, true);
                                    runOnUiThread(() -> {
                                        progressDialog.dismiss();
                                        if (commandResult.result == 0) {
                                            DabaiUtils.showDialog(MainActivity.this, "双开 \"" + name + "\" 成功！(successMsg=" + commandResult.successMsg + ")");
                                        } else {
                                            DabaiUtils.showDialog(MainActivity.this, "双开 \"" + name + "\" 失败！(errorMsg=" + commandResult.errorMsg + ")");
                                        }
                                    });
                                }).start();

                            })
                            .negativeText(R.string.cancel)
                            .show();

                }
                break;
            case "shizuku":
                //shizuku授权

                PermissionX.init(this).permissions(ShizukuApiConstants.PERMISSION)
                        .request((allGranted, grantedList, deniedList) -> {
                            if (allGranted) {

                                if (!ShizukuShell.getInstance().isAvailable()) {

                                    new MaterialDialog.Builder(this)
                                            .title(R.string.tip)
                                            .content(R.string.shizuku_stop)
                                            .positiveText(R.string.yes)
                                            .neutralText(R.string.jiaocheng)
                                            .onNeutral((dialog, which) -> DabaiUtils.openLink(this, "https://support.qq.com/products/159271/faqs/93155"))
                                            .show();

                                } else {
                                    new MaterialDialog.Builder(this)
                                            .title(R.string.tip)
                                            .content("[shizuku] 确定要双开 \"" + name + "\" 嘛？")
                                            .positiveText(R.string.yes)
                                            .onPositive((dialog, which) -> {

                                                progressDialog.setContent("正在尝试双开 \"" + name + "\" ,请稍等...");
                                                progressDialog.show();

                                                new Thread(() -> {
                                                    //尝试双开

                                                    Shell.Result installationResult = ShizukuShell.getInstance().exec(new Shell.Command("pm", "install -r --user " + DabaiUtils.getSharedPreferencesString(context, "user", "999") + " ", basePath));

                                                    runOnUiThread(() -> {
                                                        progressDialog.dismiss();
                                                        if (installationResult.exitCode == 0) {
                                                            DabaiUtils.showDialog(MainActivity.this, "双开 \"" + name + "\" 成功！(successMsg=" + installationResult.out + ")");
                                                        } else {
                                                            DabaiUtils.showDialog(MainActivity.this, "双开 \"" + name + "\" 失败！(errorMsg=" + installationResult.err + ")");
                                                        }
                                                    });
                                                }).start();

                                            })
                                            .negativeText(R.string.cancel)
                                            .show();
                                }

                            } else {
                                new MaterialDialog.Builder(this)
                                        .title(R.string.tip)
                                        .content(R.string.shizuku_stop_per)
                                        .positiveText(R.string.yes)
                                        .neutralText(R.string.jiaocheng)
                                        .onNeutral((dialog, which) -> DabaiUtils.openLink(this, "https://support.qq.com/products/159271/faqs/93155"))
                                        .show();
                            }
                        });

                break;

        }
    }


    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.menu_setting) {
            startActivity(new Intent(MainActivity.this, SettingsActivity.class));
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        SearchView searchView = (SearchView) menu.findItem(R.id.app_bar_search).getActionView();
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            // 搜索关键词完成输入
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            // 搜索关键词发生变化
            public boolean onQueryTextChange(String newText) {
                doSearch(newText);
                return true;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }


    /**
     * 搜索关键字
     */
    private void doSearch(String newText) {

        ArrayList<AppBaseInfo> resultList = new ArrayList<>();

        if (newText.equals("")) {
            adapter = new AppAdapter(appBaseInfo);
            // 设置空搜索点击事件
            adapter.setOnItemClickListener((adapter, view, position) -> {
                String name = appBaseInfo.get(position).getAppName();
                String packageName = appBaseInfo.get(position).getPackageName();
                String path = AppUtils.getAppSourceByPackageName(context, packageName);
                checkPermissions(name, path);
            });

        } else {

            for (int i = 0; i < appBaseInfo.size(); i++) {
                if (appBaseInfo.get(i).getAppName().toLowerCase().contains(newText.toLowerCase())) {
                    resultList.add(appBaseInfo.get(i));
                }
            }
            adapter = new AppAdapter(resultList);
            // 设置搜索结果点击事件
            adapter.setOnItemClickListener((adapter, view, position) -> {
                String name = resultList.get(position).getAppName();
                String packageName = resultList.get(position).getPackageName();
                String path = AppUtils.getAppSourceByPackageName(context, packageName);
                checkPermissions(name, path);
            });
        }
        amb.recyclerView.setAdapter(adapter);

    }

    // 用来计算返回键的点击间隔时间
    private long exitTime = 0;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {

            if ((System.currentTimeMillis() - exitTime) > 2000) {
                //弹出提示，可以有多种方式
                Toast.makeText(getApplicationContext(), getString(R.string.again_according_to_exit_program), Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                finish();
            }
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

}